#include "task_udps_log_comm.h"

#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"

#include "device_resource.h"

#include "OutputLog.h"
#include "w6100_socket.h"
#include "w6100_udps_comm_op.h"

#define CLIENT_TIMEOUT_SEC 10
static StackType_t xUdpsLogStack[256]; // 静态栈
static StaticTask_t xUdpsLogTCB;       // 静态 TCB（可选，省堆）
// 客户端连接状态
typedef struct
{
  uint8_t client_ip[4];
  uint16_t client_port;
  uint8_t addr_lenth;
  int is_connected;          // 连接状态（1: 已连接，0: 未连接）
  uint32_t last_active_time; // 最后活动时间（秒）
} ClientConn;
static ClientConn g_client_conn = {0}; // 全局连接状态
// 获取当前时间（秒）
static uint32_t get_current_time_sec(void)
{
  return xTaskGetTickCount() / configTICK_RATE_HZ;
}
// 处理客户端请求
static void handle_client_request(char *data, int len, uint8_t *client_ip, uint16_t client_port, uint8_t addr_lenth)
{
  int ret;
  // 更新最后活动时间
  if (len > 0)
  {
    if (strncmp(data, "CONNECT", 7) == 0)
    {
      if (g_client_conn.is_connected)
      {
        ret = memcmp(g_client_conn.client_ip, client_ip, 4);
        if ((ret == 0) && (g_client_conn.client_port == client_port))
        {
          g_client_conn.last_active_time = get_current_time_sec();
          return;
        }
        else
        {
          memcpy(g_client_conn.client_ip, client_ip, 4);
          g_client_conn.client_port = client_port;
          g_client_conn.last_active_time = get_current_time_sec();
          g_client_conn.addr_lenth = addr_lenth;
          g_client_conn.is_connected = 1;
          // LOG_I("UDP client connect %d.%d..%d.%d:%d\r\n", client_ip[0], client_ip[1], client_ip[2], client_ip[3], client_port);
        }
      }
      else
      {
        memcpy(g_client_conn.client_ip, client_ip, 4);
        g_client_conn.client_port = client_port;
        g_client_conn.last_active_time = get_current_time_sec();
        g_client_conn.addr_lenth = addr_lenth;
        g_client_conn.is_connected = 1;
        LOG_I("UDP client connect %d.%d..%d.%d:%d\r\n", client_ip[0], client_ip[1], client_ip[2], client_ip[3], client_port);
      }
    }
    else if (strncmp(data, "DISCONNECT", 10) == 0)
    {
      // 处理断开请求
      g_client_conn.is_connected = 0;
      LOG_I("UDP client disconnect!\r\n");
    }
  }
  if (g_client_conn.is_connected)
  {
    // 检查客户端是否超时
    uint32_t current_time = get_current_time_sec();
    if (current_time - g_client_conn.last_active_time > CLIENT_TIMEOUT_SEC)
    {
      g_client_conn.is_connected = 0;
      LOG_E("UDP client connect timeout!\r\n");
    }
  }
}
char *log_data_pull_from_queue = (char *)LOG_PULL_DATA_BEG_ADDR;
uint8_t log_buffer_send[1024];
static void vUdpsLogTaskEntry(void *pvParameters)
{
  (void)pvParameters;
  uint8_t from_ip[4];
  uint16_t from_port;
  uint16_t src_port;
  uint8_t addr_lenth;
  BaseType_t xStatus;
  int recv_len;
  for (;;)
  {
    if ((w6100_net_status == W6100_READY) ||
        (w6100_net_status == W6100_DHCP_FAIL))
    {
      switch (LOG_net_status)
      {
      case LOG_INIT:
        src_port = 5005;
        if (0 == W6100_udps_setup(SOCKET_LOG, &src_port, AS_IPV4))
        {
          g_log_status = 2;
          LOG_I("LOG udps setup:success!\r\n");
          LOG_INFO("LOG udps setup:success!\r\n");
          LOG_net_status = LOG_READY;
        }
        else
        {
          LOG_ERROR("LOG udps setup:fail!\r\n");
        }
        break;
      case LOG_READY:

        xStatus = xQueueReceive(xLogQueue, log_buffer_send, 0);
        if (xStatus == pdPASS)
        {
          if (xSemaphoreTake(xLogOutMutex, portMAX_DELAY) == pdPASS)
          {
            uart_send_string((const char *)log_buffer_send);
            xSemaphoreGive(xLogOutMutex);
          }
          if (g_client_conn.is_connected)
          {
            W6100_udps_send(SOCKET_LOG, log_buffer_send,
                            strlen(log_buffer_send),
                            g_client_conn.client_ip,
                            g_client_conn.client_port,
                            g_client_conn.addr_lenth);
          }
        }

        recv_len = W6100_udps_recv(SOCKET_LOG, log_buffer_send, from_ip, &from_port, &addr_lenth);
        handle_client_request((char *)log_buffer_send, recv_len, from_ip, from_port, addr_lenth);

        break;
      default:
        break;
      }
    }
    vTaskDelay(pdMS_TO_TICKS(50));
  }
}

void vUdpsLogTaskCreate(void)
{
  TaskHandle_t xHandle = NULL;

  taskENTER_CRITICAL(); // 进入临界区
  /* 创建system_led任务 - 静态方法 */
  xHandle = xTaskCreateStatic(
      (TaskFunction_t)vUdpsLogTaskEntry,                     /* 任务入口函数 */
      (const char *)"udps log",                              /* 任务名字 */
      (uint16_t)sizeof(xUdpsLogStack) / sizeof(StackType_t), /* 任务栈大小 */
      (void *)NULL,                                          /* 任务入口函数参数 */
      (UBaseType_t)10,                                       /* 任务的优先级 */
      (StackType_t *)xUdpsLogStack,                          /* 静态栈数组 */
      (StaticTask_t *)&xUdpsLogTCB);                         /* 静态TCB的地址 */

  if (xHandle != NULL)
  {
    LOG_INFO("Create RTL status check task success!\r\n");
  }
  taskEXIT_CRITICAL(); // 退出临界区，无论成功失败都要退出
}
